import cgi,os,sys,time
import types

from snakeserver.snakelet import Snakelet


class Memory(Snakelet):
    def requiresSession(self):
        return self.SESSION_WANTED
    def getDescription(self):
        return "show memory usage"
    def serve(self, request, response):
        import gc
        prev = int(request.getParameter("previous",0))
        now= len(gc.get_objects())
        delta = now-prev
        out = response.getOutput()
        print >>out, '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">'
        print >>out,'<html><head><title>Memory usage</title></head><body>'
        print >>out, "<h1>'Memory' Snakelet</h1>"
        print >>out, "<p>measured at "+time.strftime("%c")+"</p>"
        print >>out, "<p><strong>Python memory usage: %d objects (delta = %d)</strong></p>" % (now, delta)
        print >>out, "<p><a href=\"memory.sn?previous=%d\">Measure again</a></p>" % now
        print >>out, "<p><a href=\"memory.y?previous=%d\">Measure again (with ypage)</a></p>" % now
        print >>out, "</body></html>"


class Included(Snakelet):
    def requiresSession(self):
        return self.SESSION_NOT_NEEDED
    def getDescription(self):
        return "snakelet that outputs stuff for the include test"
    def serve(self, request, response):
        response.setEncoding("UTF-8")
        out = response.getOutput()
        # print >>out,"This is the Included Snakelet! Euro sign: "+u"\u20ac"
        out.write("This is the Included Snakelet! Euro sign: "+u"\u20ac")


class Encoding(Snakelet):

    def init(self):
        self.getContext().counter=0
    def requiresSession(self):
        return self.SESSION_NOT_NEEDED
    def getDescription(self):
        return "to test character encodings"

    def serve(self, request, response):
        encoding=request.getParameter("encoding") or "UTF-8"
        response.setEncoding(encoding)
        response.setContentType("text/html")
        out = response.getOutput()
        out.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">')
        out.write("<html><head><title>%s</title></head>\n" % encoding)
        out.write("<body><h2>A page with %s character-encoding</h2>\n" % encoding)
        out.write("<em>Text below generated by snakelet</em>\n")
        out.write("<p>Showing different kind of symbols ")
        out.write(u"(\N{COPYRIGHT SIGN}, \N{GREEK SMALL LETTER BETA}, \N{GREEK SMALL LETTER PI}, \N{EURO SIGN})\n")
        out.write("<br>Accented letters ")
        out.write(u"(like \N{LATIN CAPITAL LETTER C WITH CEDILLA} and \N{LATIN CAPITAL LETTER U WITH CIRCUMFLEX}), ")
        out.write("Greek letters ")
        out.write(u"(\N{GREEK SMALL LETTER ALPHA} \N{GREEK SMALL LETTER BETA} \N{GREEK SMALL LETTER GAMMA}), ")
        out.write("Arabic letters ")
        out.write(u"(\N{ARABIC LETTER SHEEN} \N{ARABIC LETTER GHAIN} \N{ARABIC LETTER YEH}), ")
        out.write("Cyrillic letters ")
        out.write(u"(\N{CYRILLIC CAPITAL LETTER BE} \N{CYRILLIC CAPITAL LETTER EF} \N{CYRILLIC CAPITAL LETTER YA}), ")
        out.write("Hebrew ")
        out.write(u"(\N{HEBREW LETTER ALEF} \N{HEBREW LETTER BET} \N{HEBREW LETTER GIMEL})\n")
        out.write("<br>And much more...")
        out.write("<br>This should be an Euro: "+unichr(0x20ac))
        out.write("<hr>The page you're looking at is a snakelet.")
        out.write("<br>You can also try out an <a href=\"encoding.y\">Ypage</a>.\n")
        out.write('<p>View this page using: ')
        out.write(' <a href="'+self.getURL()+'?encoding=UTF-7">UTF-7</a> ')
        out.write(' <a href="'+self.getURL()+'?encoding=UTF-8">UTF-8</a> ')
        out.write(' <a href="'+self.getURL()+'?encoding=UTF-16">UTF-16</a> ')
        out.write(' <a href="'+self.getURL()+'?encoding=UTF-16BE">UTF-16BE</a> ')
        out.write(' <a href="'+self.getURL()+'?encoding=UTF-16LE">UTF-16LE</a> ')
        out.write(' <a href="'+self.getURL()+'?encoding=unicode_escape">escaped unicode</a> ')
        out.write("</body></html>")

class Redirecter(Snakelet):

    def requiresSession(self):
        return self.SESSION_NOT_NEEDED

    def serve(self, request, response):
        response.setEncoding("UTF-8")
        form = request.getForm()
        arg = request.getArg()
        if arg=='redir':
            url=form['url']
            url+="?password=foobar"
            request.getContext().message="This is the message put into the request by the snakelet"
            self.redirect(url, request, response)
        elif arg=='httpredir':
            url=form['url']
            url+="?password=foobar"
            response.HTTPredirect(url)
        elif arg=='include':
            url=form['url']
            out=response.getOutput()
            print >>out, '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">'
            print >>out,'<html><head><title>Inclusion</title></head><body><h1>Include test</h1>The text in the yellow box below is included from elsewhere:</h1>'
            print >>out,'Please note that any links or images in the included page are <em>not</em> translated, and will likely be wrong.<hr>' 
            print >>out,'<table align="center" border="4" bgcolor="yellow" cellpadding="10"><tr><td>'
            request.getContext().message="This is the message put into the request by the snakelet"
            self.include(url, request, response)
            print >>out,'</td></tr></table> Here it is a second time: '
            print >>out,'<table align="center" border="4" bgcolor="yellow" cellpadding="10"><tr><td>'
            self.include(url, request, response)
            print >>out,'</td></tr></table>'
            print >>out,'<hr>This ends the include example.</body></html>'
        else:   
            out=response.getOutput()
            import urllib
            snoopUrl=urllib.quote("/test/snoop.sn?newarg=newvalue&morearg=morevalue")
            print >>out, '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">'
            print >>out,'<html><head><title>Redirection</title></head><body><h1>Redirect snakelet</h1>'
            print >>out,'<p><a href="'+self.getURL()+'?redir&amp;url=/test/test.y">Internal redirect to Ypage. Fancy redirect url stays in location bar</a>'
            print >>out,'<p><a href="'+self.getURL()+'?redir&amp;url=/test/incl.html">Internal redirect to html. Fancy redirect url stays in location bar</a>'
            print >>out,'<p><a href="'+self.getURL()+'?redir&amp;url=/test/snoop.sn">Internal redirect to Snoop page.</a>'
            print >>out,'<p><a href="'+self.getURL()+'?redir&amp;url=http://pyro.sourceforge.net/manual/PyroManual.html">Internal redirect to external link. Fancy url stays in location bar.</a>'
            print >>out,'<p><a href="'+self.getURL()+'?httpredir&amp;url=/test/test.y">HTTP (browser) redirect to Ypage. Destination url will be in location bar</a>'
            print >>out,'<p><a href="'+self.getURL()+'?httpredir&amp;url=/test/incl.html">HTTP (browser) redirect to html. Destination url will be in location bar</a>'
            print >>out,'<p><a href="'+self.getURL()+'?include&amp;url=/test/test.y">Include Ypage</a>'
            print >>out,'<p><a href="'+self.getURL()+'?include&amp;url=/test/incl.html">Include html</a>'
            print >>out,'<p><a href="'+self.getURL()+'?include&amp;url=/dir1/">Include directory listing</a>'
            print >>out,'<p><a href="'+self.getURL()+'?include&amp;url=http://pyro.sourceforge.net/manual/PyroManual.html">Include external link</a>'
            print >>out,'</body></html>'


class Error(Snakelet):
    def init(self):
        pass
    def requiresSession(self):
        return self.SESSION_NOT_NEEDED

    def serve(self, request, response):
        if request.getParameter("custom"):
            self.setErrorPage("errorpage.y")   # we will simply use the custom error Ypage for output
            # you may not call getOutput(), otherwise
            #  the redirection to the error page fails!
        else:
            self.setErrorPage(None)
            out=response.getOutput()
            out.write("This snakelet will generate an error. ")
            out.write("And it uses the default error page.")
        a=1
        b=0
        c=a/b   # BOOM !!!  ;-)
        response.getOutput().write("never reached!")


class FakeIndex(Snakelet):
    def init(self):
        pass
    def requiresSession(self):
        return self.SESSION_NOT_NEEDED

    def serve(self, request, response):
        out=response.getOutput()
        out.write("""
<html><body>
<h1>Fake index page</h1>
<p>This page is the index page of a 'fake' directory.
<p>The directory you requested in the url does not actually exist,
instead the index page is served by a special <em>index-snakelet</em>.
</body></html>""")        


class HTTPAuthenticator_management(Snakelet):

    def requiresSession(self):
        return self.SESSION_LOGIN_REQUIRED      # make sure a user is logged in ...
        # the ypage equivalent is <%@session=user%>

    def getAuthMethod(self): return ("httpbasic","Management")     # ... using http basic authentication.
        # the ypage equivalent is <%@authmethod=httpbasic%>
    
    def serve(self, request, response):
        out = response.getOutput()
        user=request.getSession().getLoggedInUser()
        print >>out, '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">'
        print >>out,'<html><head><title>Made it!</title></head><body><h2>You made it!</h2>'
        if user:
            print >>out,"<p>Authorized user: <code>"+user.userid+"</code>"
            print >>out,"<p>privileges: <code>"+self.escape(str(user.privileges))+"</code>"
        else:
            print >>out,"<p>Strange, there is no logged in user??"
        print >>out,"</body></html>"
        

class HTTPAuthenticator_backoffice(HTTPAuthenticator_management):
    def getAuthMethod(self): return ("httpbasic","Backoffice")     # ... realm = Backoffice
